/**
 * 
 */
package idv.takeshi.software.productline.bookstore.application.service.spring;

import java.util.Collection;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import idv.takeshi.software.productline.bookstore.application.service.MaintainUserAccountsService;
import idv.takeshi.software.productline.bookstore.application.service.dto.MultiUserAccountDto;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.Role;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.RoleDuplicateException;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccount;
import idv.takeshi.software.productline.bookstore.domain.model.useraccount.UserAccountRepository;

/**
 * A implementation for service MintainUserAccountsService.
 * @author takeshi
 *
 */
@Service("maintainUserAccountsService")
@Transactional
public class MaintainUserAccountsServiceImpl implements
		MaintainUserAccountsService {
	
	@Autowired
	private UserAccountRepository userAccountRepository;
	
	@Autowired
	private PasswordEncoder passwordEncoder;

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MintainUserAccountsService#getUserAccountsByRoleAccountNameAndAccountType(java.lang.String, java.lang.String, java.lang.String)
	 */
	public Set<UserAccount> getUserAccountsByRoleAccountNameAndAccountType(
			String role, String accountName, String accountType) {
		return this.userAccountRepository.findByRoleAccountNameAndAccountType(role, accountName, accountType);
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MaintainUserAccountsService#getUserAccountById(java.lang.Long)
	 */
	public UserAccount getUserAccountById(Long id) {
		return this.userAccountRepository.findById(id);
	}

	
	
	
	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MaintainUserAccountsService#updateUserAccount(idv.takeshi.software.productline.bookstore.application.service.dto.MultiUserAccountDto)
	 */
	public void updateUserAccount(MultiUserAccountDto userAccountDto) throws RoleDuplicateException {
		Validate.notNull(userAccountDto, "userAccountDto shall always not be null");
		Collection<Role> removeRoles = null;
		UserAccount userAccount = this.userAccountRepository.findById(userAccountDto.getId());
		removeRoles = userAccountDto.loadModel(userAccount);
		if(CollectionUtils.isNotEmpty(removeRoles))
			this.userAccountRepository.remove(removeRoles);
		
		if(!userAccount.getPassword().equals(userAccount.getOriginalPassword())){
			String newPassword = userAccount.getOriginalPassword();
			String encodedNewPassword = this.passwordEncoder.encodePassword(newPassword, null);
			userAccount.setPassword(encodedNewPassword);
		}
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.software.productline.bookstore.application.service.MaintainUserAccountsService#getUserAccountByName(java.lang.String)
	 */
	public UserAccount getUserAccountByName(String name) {
		Validate.notEmpty(name, "name shall always not be null/empty");
		return this.userAccountRepository.findByAccountName(name);
	}

}
